import traceback
from flask import Blueprint, request, abort
from flask_restful import reqparse, inputs, Resource, Api, fields, marshal_with
from ....models.database import db, auto_commit
from ....decorator.consolejwt import console_token
from ...res import output_json
from ....libs.unit import formatDate, abort_msg
from ....models.common.type import Type
from ....libs.tree import UpdateTable


# 蓝图并放入 restful
types = Blueprint('types', __name__, url_prefix='/c-api/types')
api = Api(types)

# 统一封装 API 返回值
@api.representation('application/json')
def out_json(data, code, headers=None):
    return output_json(data, code, headers=None)


# 封装返回的数据格式
resource_name = {
    'id': fields.Integer,
    'name': fields.String
}
class ListType(Resource):
    @console_token
    @marshal_with(resource_name, envelope='resource')
    def get(self):
        with auto_commit():
            parentid = request.values.get('parentid', 0)
            lists = Type.query.order_by(Type.id.desc()).filter(Type.parentid == parentid).all()
        return lists


# 转成树形分类
def toTree(data, pid):
    tree = []
    for i in data:
        if i.parentid == pid:
            tree.append({'type_id': i.id, 'title': i.name,'expand': True, 'children': toTree(data, i.id)})
    return tree


class TypeTree(Resource):
    @console_token
    def get(self):
        with auto_commit():
            c = Type.query.order_by(Type.sort.asc()).all()
            c = toTree(c, 0)
        return {'resource': c}

# 下拉分类


class TypeSelect(Resource):
    @console_token
    def get(self):
        with auto_commit():
            c = Type.query.order_by(Type.sort.asc())
            res = []
            f_types = c.filter(Type.parentid == 0).all()
            # 只查三级选项出来
            for f in f_types:
                # 一级
                res.append({'label': f.name, 'value': f.id})
                # 二级
                s_types = c.filter(Type.parentid == f.id).all()
                for s in s_types:
                    res.append({'label': '|- ' + s.name, 'value': s.id})
                    # 三级
                    t_types = c.filter(Type.parentid == s.id).all()
                    for t in t_types:
                        res.append({'label': '||- ' + t.name, 'value': t.id})
        return {'resource': res}

# 封装返回的数据格式
resource_fields = {
    'id': fields.Integer,
    'parentid': fields.Integer,
    'name': fields.String,
    'sort': fields.Integer
}


class DetailMenu(Resource):
    @console_token
    @marshal_with(resource_fields, envelope='resource')
    def get(self):
        # 请求验证
        parser = reqparse.RequestParser()
        parser.add_argument('type_id', type=int,
                            help='分类 ID 必须填写', location=['form', 'args'], required=True, action='store')
        args = parser.parse_args()
        with auto_commit():
            c = Type.query.filter(Type.id == args.get('type_id')).first()
        return c


class CreateType(Resource):
    @console_token
    def post(self):
        # 请求验证
        parser = reqparse.RequestParser()
        parser.add_argument('parentid', type=inputs.natural,
                            help='父 ID 必须填写', location=['form', 'args'], required=True, action='store')
        parser.add_argument('name', type=str,
                            help='分类名称必须填写', location=['form', 'args'], required=True, action='store')
        parser.add_argument('sort', type=inputs.natural,
                            help='权限标识必须填写', location=['form', 'args'], required=False, action='store', default=0)
        args = parser.parse_args()
        with auto_commit():
            c = Type()
            c.name = args.get('name')
            c.parentid = args.get('parentid')
            c.sort = args.get('sort')
            db.session.add(c)
            # 更新表
            t = UpdateTable()
            t.update(Menu)
        return {'resource': ''}


class EditType(Resource):
    @console_token
    # @marshal_with(resource_fields, envelope='resource')
    def put(self):
        # 请求验证
        parser = reqparse.RequestParser()
        parser.add_argument('type_id', type=inputs.positive,
                            help='分类 ID 必须填写', location=['form', 'args'], required=True, action='store')
        parser.add_argument('parentid', type=inputs.natural,
                            help='父 ID 必须填写', location=['form', 'args'], required=True, action='store')
        parser.add_argument('name', type=str,
                            help='分类名称必须填写', location=['form', 'args'], required=True, action='store')
        parser.add_argument('sort', type=inputs.natural,
                            help='权限标识必须填写', location=['form', 'args'], required=False, action='store', default=0)
        args = parser.parse_args()
        with auto_commit():
            c = Type.query.filter(Type.id == args.get('type_id')).first()
            c.name = args.get('name')
            c.parentid = args.get('parentid')
            c.sort = args.get('sort')
            # 更新表
            t = UpdateTable()
            t.update(Menu)
        return {'resource': ''}


class DeleteType(Resource):
    @console_token
    # @marshal_with(resource_fields, envelope='resource')
    def delete(self):
        # 请求验证
        parser = reqparse.RequestParser()
        parser.add_argument('type_id', type=inputs.positive,
                            help='分类 ID 必须填写', location=['form', 'args'], required=True, action='store')
        args = parser.parse_args()
        with auto_commit():
            c = Type.query.filter(Type.id == args.get('type_id')).first()
            allids = c.arrchildid.split(',')
            Type.query.filter(Type.id.in_(allids)).delete(synchronize_session=False)
            # 更新表
            t = UpdateTable()
            t.update(Menu)
        return {'resource': ''}


api.add_resource(TypeTree, '/tree')
api.add_resource(TypeSelect, '/select')
api.add_resource(DetailType, '/detail')
api.add_resource(CreateType, '/create')
api.add_resource(EditType, '/edit')
api.add_resource(DeleteType, '/delete')
